home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1995…tember: Reference Library / Dev.CD Sep 95 RL / Dev.CD Sep 95 RL.toast / mac / Technical Documentation / develop / develop Issue 15 code / Symmetry & Tiles / Tiler Code / Symmetry Utils.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-09-13  |  6.0 KB  |  221 lines  |  [TEXT/KAHL]

  1. #include     <graphics libraries.h>
  2. #include     <graphics toolbox.h>
  3. #include    "TileConstants.h"
  4. #include    "SymmetryUtils.h"
  5.  
  6. //-------------------------------------------------------------
  7. //    Routine to create the various symmetry operation shapes    
  8.  
  9. gxShape MakeOpShape(long theType)
  10. {
  11.     // Cap stuff
  12.     gxCapRecord        myCapRec;
  13.      gxDashRecord     theDashRecord;
  14.     gxShape            theShape = nil, tempShape, otherTempShape;
  15.     long            genericLine[] = { 0, 0, 0, kStartingGridSize };
  16.     gxRectangle        roundCapBounds = {-ff(1), -ff(1), ff(1), ff(1)},
  17.                     dashRect = {0, -fl(.5), ff(10), fl(.5)},
  18.                     ovalRect = {-ff(1), -ff(2), ff(1), ff(2)};
  19.     gxPoint            aPoint = {0, 0};
  20.     long            arrowGon[] = {    4,
  21.                                     ff(5), 0,
  22.                                     0, -ff(2),
  23.                                     0, 0,
  24.                                     0, ff(2)    };
  25.                                 
  26.     switch(theType)
  27.     {
  28.         case transOp:    // translation shape, arrow with starting dot
  29.             theShape = GXNewLine((gxLine *)genericLine);
  30.             GXSetShapePen(theShape, ff(3));
  31.             
  32.             // arrow head and dot are line caps
  33.             tempShape = NewPolygon((gxPolygon *) arrowGon);
  34.             otherTempShape = NewArc(&roundCapBounds, ff(0), ff(360), true);
  35.             myCapRec.startCap = otherTempShape;
  36.             myCapRec.endCap = tempShape;
  37.             myCapRec.attributes = gxNoAttributes;
  38.             GXSetShapeCap(theShape, &myCapRec);
  39.             SetShapeCommonColor(theShape, kTranslateColor);
  40.             GXDisposeShape(tempShape);
  41.             GXDisposeShape(otherTempShape);
  42.             break;
  43.             
  44.         case reflOp:    // reflection, a simple line
  45.             theShape =  GXNewLine((gxLine *)genericLine);
  46.             GXSetShapePen(theShape, ff(3));
  47.             GXScaleShape(theShape, 0, ff(2), 0, 0);
  48.             GXMoveShape(theShape, 0, -(kStartingGridSize / 2) );
  49.             SetShapeCommonColor(theShape, kMirrorColor);
  50.             break;
  51.             
  52.         case glideOp:    // glide reflection, a dashed line with arrow head
  53.             theShape =  GXNewLine((gxLine *)genericLine);
  54.             GXSetShapePen(theShape, ff(3));
  55.             // GXMoveShape(theShape, 0, -(kStartingGridSize / 2) );
  56.             
  57.             // Add the cap
  58.             tempShape = NewPolygon((gxPolygon *) arrowGon);
  59.             myCapRec.startCap = nil;
  60.             myCapRec.endCap = tempShape;
  61.             myCapRec.attributes = gxNoAttributes;
  62.             GXSetShapeCap(theShape, &myCapRec);
  63.             GXDisposeShape(tempShape);
  64.             
  65. /*             // Add the dash
  66.             tempShape = GXNewRectangle(&dashRect);
  67.             theDashRecord.attributes = gxClipDash; // + gxAutoAdvanceDash;
  68.             theDashRecord.dash = tempShape;
  69.             theDashRecord.advance = ff(16); 
  70.             theDashRecord.phase = 0; 
  71.             theDashRecord.scale = ff(1); 
  72.             GXSetShapeDash(theShape, &theDashRecord);
  73.             GXDisposeShape(tempShape);
  74.  */            
  75.             // Set color
  76.             SetShapeCommonColor(theShape, kGlideColor);
  77.             break;
  78.             
  79.         case roto2Op:    // center of 180 degree rotation
  80.             theShape = GXNewPoint(&aPoint);
  81.             GXSetShapePen(theShape, ff(5));
  82.             
  83.             // oval is a line cap
  84.             tempShape = NewOval(&ovalRect);
  85.             myCapRec.startCap = tempShape;
  86.             myCapRec.endCap = nil;
  87.             myCapRec.attributes = gxNoAttributes;
  88.             GXSetShapeCap(theShape, &myCapRec);
  89.             SetShapeCommonColor(theShape, kRotoColor);
  90.             GXDisposeShape(tempShape);
  91.             break;
  92.     }
  93.     return theShape;
  94. }
  95.  
  96.  
  97. // Moves the glide shape as appropriate. Gnarly.
  98. void DragGlideShape(gxShape dragShape, gxPoint *newPt, gxPoint *oldPt,
  99.                         gxPoint *anchor, long constraint, Boolean arrowHit)
  100. {
  101.     fixed    xd = newPt->x - anchor->x,
  102.             lxd = labs(newPt->x - anchor->x);
  103.     fixed    yd = newPt->y - anchor->y,
  104.             lyd = labs(newPt->y - anchor->y);
  105.     fixed    theLine[4];
  106.     //fixed    slope;
  107.     
  108.     GXGetLine(dragShape, (gxLine *)theLine);
  109.     //slope = FixDiv(theLine[3] - theLine[1], theLine[2] - theLine[0]);
  110.     
  111.     // Set up to move shape
  112.     switch(constraint)
  113.     {
  114.         case constrainH: // Assumes a vertical glide line, pointing down
  115.             // If it's in bounds, just set the x coords to the new point's
  116.             if(    lxd > kMinDistance && lxd < kMaxDistance )
  117.             {
  118.                 theLine[0] = theLine[2] = newPt->x;
  119.             }
  120.             else if( lxd > kMaxDistance )
  121.             {
  122.                 // Set to the max
  123.                 theLine[0] = theLine[2] = 
  124.                     anchor->x + ( (xd < 0) ? -kMaxDistance : kMaxDistance);
  125.             }
  126.             else if( lxd < kMinDistance )
  127.             {
  128.                 // Set to the min
  129.                 theLine[0] = theLine[2] = 
  130.                     anchor->x + ( (xd < 0) ? -kMinDistance : kMinDistance);
  131.             }
  132.  
  133.             // Set the length if arrow is hit
  134.             if(arrowHit)
  135.             {
  136.                 // If it's in bounds, just set the y coord to the new point's
  137.                 if(    yd > kMinDistance && yd < kMaxDistance )
  138.                 {
  139.                     theLine[3] = newPt->y;
  140.                 }
  141.                 else if( yd > kMaxDistance )
  142.                 {
  143.                     // Set to the max
  144.                     theLine[3] = anchor->y + kMaxDistance;
  145.                 }
  146.                 else if( yd < kMinDistance )
  147.                 {
  148.                     // Set to the min
  149.                     theLine[3] = anchor->y + kMinDistance;
  150.                 }
  151.             }
  152.             break;
  153.         
  154.         default:
  155.             break;
  156.     }
  157.     GXSetLine(dragShape, (gxLine *)theLine);
  158. }
  159.  
  160. // Moves the line shape as appropriate.
  161. void DragLineShape(gxShape dragShape, gxPoint *newPt, gxPoint *oldPt,
  162.                         gxPoint *anchor, long constraint)
  163. {
  164.     fixed    xd = newPt->x - anchor->x,
  165.             lxd = labs(newPt->x - anchor->x);
  166.     fixed    yd = newPt->y - anchor->y,
  167.             lyd = labs(newPt->y - anchor->y);
  168.     fixed    theLine[4];
  169.     //fixed    slope;
  170.     
  171.     GXGetLine(dragShape, (gxLine *)theLine);
  172.     //slope = FixDiv(theLine[3] - theLine[1], theLine[2] - theLine[0]);
  173.     
  174.     // Set up to move shape
  175.     switch(constraint)
  176.     {
  177.         case constrainH:
  178.             // If it's in bounds, just set the x coords to the new point's
  179.             if(    lxd > kMinDistance && lxd < kMaxDistance )
  180.             {
  181.                 theLine[0] = theLine[2] = newPt->x;
  182.             }
  183.             else if( lxd > kMaxDistance )
  184.             {
  185.                 // Set to the max
  186.                 theLine[0] = theLine[2] = 
  187.                     anchor->x + ( (xd < 0) ? -kMaxDistance : kMaxDistance);
  188.             }
  189.             else if( lxd < kMinDistance )
  190.             {
  191.                 // Set to the min
  192.                 theLine[0] = theLine[2] = 
  193.                     anchor->x + ( (xd < 0) ? -kMinDistance : kMinDistance);
  194.             }
  195.             break;
  196.         
  197.         case constrainV:
  198.             // If it's in bounds, just set the y coords to the new point's
  199.             if(    lyd > kMinDistance && lyd < kMaxDistance )
  200.             {
  201.                 theLine[0] = theLine[2] = newPt->y;
  202.             }
  203.             else if( lyd > kMaxDistance )
  204.             {
  205.                 // Set to the max
  206.                 theLine[0] = theLine[2] = 
  207.                     anchor->y + ( (yd < 0) ? -kMaxDistance : kMaxDistance);
  208.             }
  209.             else if( lyd < kMinDistance )
  210.             {
  211.                 // Set to the min
  212.                 theLine[0] = theLine[2] = 
  213.                     anchor->y + ( (yd < 0) ? -kMinDistance : kMinDistance);
  214.             }
  215.             break;
  216.         default:
  217.             break;
  218.     }
  219.     GXSetLine(dragShape, (gxLine *)theLine);
  220. }
  221.